﻿using Api.Catalog.Models;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Net;
using System.Security.Claims;
using System.Text;
using WebApplication3.Models;

namespace Api.Catalog
{
    public class TokenHelper: ITokenHelper
    {
        private IOptions<JWTConfig> _options;
        public TokenHelper(IOptions<JWTConfig> options)
        {
            _options = options;
        }

        public Token CreateToken(User user)
        {
            //Claim[] claims = { new Claim(ClaimTypes.NameIdentifier, user.Code), new Claim(ClaimTypes.Name, user.Name) };

            //Tenant
            //
            //foreach (var item in userRoles)
            //    options.AddPolicy(item, policy => policy.RequireClaim(nameof(SysRole), item));

            var claims = new Claim[]
            {
                new Claim(nameof(TokenPayload.userid), user.Code.ToString()),
                new Claim(nameof(TokenPayload.tenant), user.Tenant.ToString()),
                new Claim(nameof(TokenPayload.aud), user.Aud.ToString()),
                new Claim(nameof(TokenPayload.nickename), user.Name.ToString())
            };

            //var claims = new Claim[] {
            //             new Claim(ClaimTypes.Name, user.Name),
            //             new Claim(ClaimTypes.Role, "Admin")
            //         };
            return CreateToken(claims);
        }
        private Token CreateToken(Claim[] claims)
        {
            var now = DateTime.Now; var expires = now.Add(TimeSpan.FromMinutes(_options.Value.AccessTokenExpiresMinutes));
            var token = new JwtSecurityToken(
                issuer: _options.Value.Issuer,
                audience: _options.Value.Audience,
                claims: claims,
                notBefore: now,
                expires: expires,
                signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_options.Value.IssuerSigningKey)), SecurityAlgorithms.HmacSha256));
            return new Token { TokenContent = new JwtSecurityTokenHandler().WriteToken(token), Expires = expires };
        }


        public TokenModel NewCreateToken(User user)
        {
            var claims = new Claim[]
            {
                new Claim(nameof(TokenPayload.userid), user.Code.ToString()),
                new Claim(nameof(TokenPayload.tenant), user.Tenant.ToString()),
                new Claim(nameof(TokenPayload.aud), user.Aud.ToString()),
                new Claim(nameof(TokenPayload.nickename), WebUtility.UrlEncode(user.Name ?? string.Empty))
            };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_options.Value.IssuerSigningKey));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var jwtSecurityToken = new JwtSecurityToken(
                issuer: _options.Value.Issuer,
                audience: _options.Value.Audience,
                signingCredentials: creds,
                claims: claims,
                notBefore: DateTime.Now,
                expires: DateTime.Now.AddSeconds(_options.Value.AccessTokenExpiresMinutes));

            string token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
            return new TokenModel
            {
                AccessToken = token,
                AuthDate = new DateTimeOffset(jwtSecurityToken.ValidFrom).ToUnixTimeSeconds(),
                ExprieDate = new DateTimeOffset(jwtSecurityToken.ValidTo).ToUnixTimeSeconds()
            };
        }

    }
}
